package org.csu.mypetstorecmsapi.controller;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import org.csu.mypetstorecmsapi.common.BaseResponse;
import org.csu.mypetstorecmsapi.domain.Admin;
import org.csu.mypetstorecmsapi.service.AdminService;
import org.csu.mypetstorecmsapi.util.JwtUtil;
import org.csu.mypetstorecmsapi.util.Md5Util;
import org.csu.mypetstorecmsapi.util.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@Validated
public class AdminController {

    @Autowired
    private AdminService adminService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/admins/register")
    public BaseResponse<Object> register(@Pattern(regexp = "^\\S{3,10}$") @NotBlank(message = "用户名不能为空") String username,
                                      @Pattern(regexp = "^\\S{5,16}$") @NotBlank(message = "密码不能为空") String password) {
        //查询该用户名是否被占用
        Admin admin = adminService.getAdminByUsername(username);

        if(admin == null) {
            adminService.register(username,password);
            return BaseResponse.createForSuccess();
        }

        return BaseResponse.createForError("用户名已被占用");
    }

    @PostMapping("/tokens/login")
    public BaseResponse<Object> login(@RequestParam("username") @NotBlank(message = "用户名不能为空") String username,
                                      @RequestParam("password") @NotBlank(message = "密码不能为空") String password){
        //查询该用户名是否存在
        Admin admin = adminService.getAdminByUsername(username);

        if(admin == null){
            return BaseResponse.createForError("用户名不存在");
        }

        //检验密码正确后返回JWT令牌
        if(Md5Util.getMD5String(password).equals(admin.getPassword())){
            Map<String,Object> claims = new HashMap<>();
            claims.put("username", admin.getUsername());
            claims.put("password", admin.getPassword());
            String token = JwtUtil.genToken(claims);

            //把token存储到redis中
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            operations.set(token,token,1, TimeUnit.HOURS);
            return BaseResponse.createForSuccess(token);
        }

        return BaseResponse.createForError("密码错误");
    }

    @DeleteMapping("/tokens/logout")
    public BaseResponse<Object> logout(@RequestHeader("Authorization") String token){
        //删除redis中对应的token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return BaseResponse.createForSuccess();
    }

    @PatchMapping("/admins/edit")
    public BaseResponse<Admin> editPassword(HttpServletResponse response,
                                            @RequestBody Map<String, String> params,
                                            @RequestHeader("Authorization") String token){
        //校验参数
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            response.setStatus(400);
            return BaseResponse.createForError("缺少参数");
        }

        if(newPwd.length() < 5 || newPwd.length() > 16){
            response.setStatus(500);
            return BaseResponse.createForError("参数非法");
        }

        //原密码是否正确
        //调用userService根据用户名拿到原密码,再和old_pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        Admin admin = adminService.getAdminByUsername(username);
        if (!admin.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return BaseResponse.createForError("原密码填写不正确");
        }

        //newPwd和rePwd是否一样
        if (!rePwd.equals(newPwd)){
            return BaseResponse.createForError("两次填写的新密码不一样");
        }

        //调用service完成密码更新
        adminService.updatePassword(newPwd);
        //删除redis中对应的token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return BaseResponse.createForSuccess();
    }
}
